package sis.studentinfo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

public class Student implements Serializable {
    //学生id
    private String id;
    //学生姓名
    private String name;
    //学生学分
    private int credits;
    //学分合格分数线
    public static final int CREDITS_REQUIRED_FOR_FULL_TIME = 12;
    //名称最大长度
    public static final int MAX_NAME_PARTS = 3;
    //本地学生 生源
    public static final String IN_STATE = "CO";
    //学生生源
    private String state = "";
    //学科得分等级
    private List<Grade> grades = new ArrayList<>();
    //姓名第一个字
    private String firstName = "";
    //姓名第二个字
    private String middleName = "";
    //姓名第三个字
    private String lastName;
    //学生缴费情况
    private List<Integer> charges = new ArrayList();
    //抛出异常提示
    public static final String TOO_MANY_NAME_PARTS_MSG = "Student name '%s' contains more than %d parts";
    //日志记录
    public final static Logger logger = Logger.getLogger(Student.class.getName());

    //添加缴费
    public void addCharge(int charge) {
        charges.add(new Integer(charge));
    }

    //查询总缴费额
    public int totalCharges() {
        int total = 0;
        for (Integer charge : charges) {
            total += charge;
        }
        return total;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    //姓名第一个字
    public String getFirstName() {
        return this.firstName;
    }

    //姓名第二个字
    public String getMiddleName() {
        return this.middleName;
    }

    //姓名第三个字
    public String getLastName() {
        return this.lastName;
    }



    //全部等级
    public enum Grade {
        A(4), B(3), C(2), D(1);
        private int points;

        Grade(int points) {
            this.points = points;
        }

        int getPoints() {
            return points;
        }
    }

    ;
    //默认评分规则
    private transient GradingStrategy gradingStrategy = new BasicGradingStrategy();

    //创建学生
    public Student(String fullName) {
        this.name = fullName;
        //默认学分0
        this.credits = 0;
        //分割姓名
        List<String> nameParts = split(fullName);
        if (nameParts.size() > MAX_NAME_PARTS) {
            String message = String.format(Student.TOO_MANY_NAME_PARTS_MSG, fullName, Student.MAX_NAME_PARTS);
            logger.info(message);
            throw new StudentNameFormatException(message);
        }
        //设置姓名
        setName(nameParts);
    }


    //分割姓名
    private List<String> split(String string) {
        List<String> list = new ArrayList<>();
        for (String name : name.split(" ")) {
            list.add(name);
        }
        return list;
    }

    //设置姓名
    private void setName(List<String> nameParts) {
        //被移除的最后一个元素肯定是 第三个字
        this.lastName = removeLast(nameParts);
        //第二次移除 这时如果list已经为没有元素也会返回 ""
        String name = removeLast(nameParts);
        //如果第二次移除后集合已经没有元素了
        //那fristName要么等于 "" 要么有具体的值
        if (nameParts.isEmpty()) {
            this.firstName = name;
        } else {
            //设置第二个值
            this.middleName = name;
            //取出第三个值
            this.firstName = removeLast(nameParts);
        }
    }

    //用来获取名字 中 最后的元素
    private String removeLast(List<String> list) {
        if (list.isEmpty()) {
            return "";
        }
        return list.remove(list.size() - 1);
    }

    //获取学生姓名
    public String getName() {
        return name;
    }

    //学生学分是否合格
    public boolean isFullTime() {
        return this.credits >= Student.CREDITS_REQUIRED_FOR_FULL_TIME;
    }

    //获取学生学分
    public int getCredits() {
        return this.credits;
    }

    //增加学分
    public void addCredits(int credits) {
        this.credits += credits;
    }

    //是否是本地学生
    public boolean isInState() {
        return state.equals(Student.IN_STATE);
    }

    //设置学生生源
    public void setState(String state) {
        state.toUpperCase();
        this.state = state;
    }

    //添加学生科目评级
    public void addGrade(Grade grade) {
        this.grades.add(grade);
    }

    //获取学生平均分
    public double getGpa() {
        // logger.fine("begin getGpa " + System.currentTimeMillis());
        if (this.grades.isEmpty()) {
            return 0.0;
        }
        double total = 0.0;
        //遍历学生评分,根据该学生的评分规则,计算学分总数
        for (Grade grade : this.grades) {
            total += this.gradingStrategy.getGradePointsFor(grade);
        }
        //  logger.fine("end getGpa " + System.currentTimeMillis());
        //算平均值
        return total / this.grades.size();
    }

    //设置该学生评分规则
    public void setGradingStrategy(GradingStrategy gradingStrategy) {
        this.gradingStrategy = gradingStrategy;
    }

}
